# -*- coding: utf-8 -*-

from odoo import models, fields, api, _
from odoo.exceptions import ValidationError


class CpqChangeRequest(models.Model):
    _name = 'cpq.change.request'
    _description = '变更请求(ECR/PCR)'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _rec_name = 'name'
    _order = 'create_date desc'
    
    # ============ 基础信息 ============
    name = fields.Char(
        string='变更编号',
        required=True,
        copy=False,
        readonly=True,
        default=lambda self: _('New')
    )
    
    request_type = fields.Selection([
        ('ecr', '工程变更请求(ECR)'),
        ('pcr', '产品变更请求(PCR)')
    ], string='请求类型', required=True, default='ecr')
    
    # ============ 关联对象 ============
    quotation_id = fields.Many2one(
        'cpq.quotation',
        string='原报价单',
        tracking=True
    )
    
    configuration_id = fields.Many2one(
        'cpq.configuration',
        string='原配置'
    )
    
    # ============ 变更内容 ============
    change_description = fields.Text(
        string='变更描述',
        required=True,
        tracking=True
    )
    
    change_reason = fields.Selection([
        ('customer_request', '客户需求变更'),
        ('design_optimization', '设计优化'),
        ('cost_reduction', '成本降低'),
        ('quality_improvement', '质量改进'),
        ('compliance', '法规符合性')
    ], string='变更原因', tracking=True)
    
    # ============ 变更明细(条目化) ============
    change_item_ids = fields.One2many(
        'cpq.change.item',
        'change_request_id',
        string='变更条目'
    )
    
    # ============ 影响分析 ============
    cost_impact = fields.Monetary(
        string='成本影响',
        compute='_compute_impact',
        store=True,
        currency_field='currency_id'
    )
    
    lead_time_impact = fields.Integer(
        string='交期影响(天)'
    )
    
    requires_new_quote = fields.Boolean(
        string='需要重新报价',
        default=True
    )
    
    currency_id = fields.Many2one(
        'res.currency',
        default=lambda self: self.env.company.currency_id,
        string='货币'
    )
    
    # ============ 新版本报价 ============
    new_quotation_id = fields.Many2one(
        'cpq.quotation',
        string='新版本报价',
        readonly=True
    )
    
    # ============ 状态 ============
    state = fields.Selection([
        ('draft', '草稿'),
        ('submitted', '已提交'),
        ('impact_analysis', '影响分析中'),
        ('approved', '已批准'),
        ('rejected', '已拒绝'),
        ('implemented', '已实施')
    ], string='状态', default='draft', tracking=True, required=True)
    
    # ============ 责任人 ============
    requester_id = fields.Many2one(
        'res.users',
        string='发起人',
        default=lambda self: self.env.user,
        tracking=True
    )
    
    approver_id = fields.Many2one(
        'res.users',
        string='批准人',
        tracking=True
    )
    
    # ============ 备注 ============
    notes = fields.Text(
        string='备注'
    )
    
    # ============ 计算字段 ============
    @api.depends('change_item_ids', 'change_item_ids.cost_delta')
    def _compute_impact(self):
        """计算变更的成本影响"""
        for record in self:
            record.cost_impact = sum(record.change_item_ids.mapped('cost_delta'))
    
    # ============ CRUD ============
    @api.model
    def create(self, vals):
        """创建时自动生成编号"""
        if vals.get('name', _('New')) == _('New'):
            if vals.get('request_type') == 'ecr':
                vals['name'] = self.env['ir.sequence'].next_by_code('cpq.change.request.ecr') or _('New')
            else:
                vals['name'] = self.env['ir.sequence'].next_by_code('cpq.change.request.pcr') or _('New')
        return super(CpqChangeRequest, self).create(vals)
    
    # ============ 业务方法 ============
    def action_submit(self):
        """提交变更请求"""
        self.ensure_one()
        if not self.change_item_ids:
            raise ValidationError('请至少添加一个变更条目！')
        self.state = 'submitted'
    
    def action_analyze_impact(self):
        """分析变更影响"""
        self.ensure_one()
        
        if not self.quotation_id:
            raise ValidationError('必须关联原报价单才能分析影响！')
        
        # 创建新版本报价
        new_quotation = self.quotation_id.copy({
            'version': self.quotation_id.version + 1,
            'parent_quotation_id': self.quotation_id.id,
            'change_description': self.change_description,
            'change_request_id': self.id,
            'state': 'draft'
        })
        
        # 应用变更到新配置
        if self.quotation_id.configuration_id:
            new_configuration = self.quotation_id.configuration_id.copy()
            for change_item in self.change_item_ids:
                change_item._apply_to_configuration(new_configuration)
            new_quotation.configuration_id = new_configuration
        
        # 重新核算成本
        new_quotation.action_calculate_cost()
        
        self.new_quotation_id = new_quotation
        self.state = 'impact_analysis'
        
        return {
            'type': 'ir.actions.act_window',
            'name': '变更影响分析',
            'res_model': 'cpq.quotation',
            'res_id': new_quotation.id,
            'view_mode': 'form',
            'target': 'current'
        }
    
    def action_approve(self):
        """批准变更"""
        self.ensure_one()
        self.write({
            'state': 'approved',
            'approver_id': self.env.user.id
        })
    
    def action_reject(self):
        """拒绝变更"""
        self.ensure_one()
        self.state = 'rejected'
    
    def action_implement(self):
        """实施变更"""
        self.ensure_one()
        if self.state != 'approved':
            raise ValidationError('只有已批准的变更才能实施！')
        self.state = 'implemented'

